package com.kandy.smart.trace.dubbo.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.kandy.smart.trace.TraceContext;
import com.kandy.smart.trace.TraceThread;
import com.kandy.smart.trace.constant.TraceConstant;
import com.kandy.smart.trace.utils.IPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.util.Arrays;

/**
 * Created by kandy on 18/8/14.
 */
@Activate(group = { Constants.PROVIDER },order = -10000)
public class TraceProviderFilter implements Filter {
    private static Logger logger = LoggerFactory.getLogger(TraceProviderFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        if(Boolean.TRUE.toString().equals(invocation.getAttachments().get(Constants.ASYNC_KEY))){
            RpcContext.getContext().getAttachments().remove(Constants.ASYNC_KEY);
        }

        // 获取上下文
        RpcContext rpcContext = RpcContext.getContext();

        TraceContext traceContext = TraceThread.getTraceThreadData(Thread.currentThread());
//        traceContext.setThreadId(UUID.randomUUID().toString().replaceAll("-","").toLowerCase());
        traceContext.setThreadId(String.valueOf(Thread.currentThread().getId()));
        traceContext.setTraceId(rpcContext.getAttachment(TraceConstant.TRACE_ID));
        traceContext.setParentId(rpcContext.getAttachment(TraceConstant.PARENT_ID));
        traceContext.setAppId(rpcContext.getAttachment(TraceConstant.CHILD_ID));
        traceContext.setRemoteIp(rpcContext.getAttachment(TraceConstant.REMOTE_IP));
        traceContext.setLocalIp(IPUtil.getLocalHostIp());

        // 设置日志
        MDC.put("ThreadID",traceContext.getThreadId());
        MDC.put("TraceID",traceContext.getTraceId());
        MDC.put("ParentID",traceContext.getParentId());
        MDC.put("APPID",traceContext.getAppId());
        MDC.put("localIp",traceContext.getLocalIp());

        long start = System.currentTimeMillis();
        Result result = invoker.invoke(invocation);
        long elapsed = System.currentTimeMillis() - start;
        if (invoker.getUrl() != null) {
            logger.info("[{}], [{}], {}, [{}], [{}], [{}] ",invoker.getInterface(), invocation.getMethodName(), Arrays.toString(invocation.getArguments()), result.getValue(), result.getException(), elapsed);
        }
        return result;
    }
}
